package co.bugu.es8.infra.repo;

import co.bugu.es8.infra.entity.User;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.BulkResponse;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BaseEsJavaRepo<T> {
    @Autowired
    ElasticsearchClient client;


    public Boolean createIndex(String indexName) throws IOException {
        BooleanResponse response = client.indices().exists(builder -> builder.index(indexName));
        if (response.value()) {
            log.info("索引{}已经存在", indexName);
            return true;
        }

        return client.indices().create(c -> c.index(indexName)).acknowledged();
    }

    public Boolean deleteIndex(String indexName) throws IOException {
        BooleanResponse response = client.indices().exists(builder -> builder.index(indexName));
        if (!response.value()) {
            log.info("索引{}不存在", indexName);
            return false;
        }
        return client.indices().delete(c -> c.index(indexName)).acknowledged();
    }

    public Boolean save(String indexName, T obj) throws IOException {
        IndexResponse res = client.index(builder -> builder.index(indexName).id("11").document(obj));
        String s = res.result().jsonValue();
        log.info("添加数据成功：{}", s);
        return true;
    }

    /**
     * 批量添加
     *
     * @param indexName
     * @param list
     * @return
     * @throws IOException
     */
    public Boolean batchSave(String indexName, List<T> list) throws IOException {
        if (CollectionUtils.isEmpty(list)) {
            throw new RuntimeException("批量添加的对象不存在");
        }
        List<BulkOperation> ops = list.stream().map(user -> BulkOperation.of(op -> op.index(idx -> idx.index(indexName).document(user)))).collect(Collectors.toList());
        BulkResponse res = client.bulk(builder -> builder.index(indexName).operations(ops));
        return res.errors();
    }

    public List<User> search() {
        return null;
    }

    /**
     * id查询
     *
     * @param
     * @return
     * @author alei
     * @date 2025/4/28 15:21
     */
//    public T findById(String indexName, Long id) throws IOException {
//        //      从es中查询id为11的user信息
//        T obj = client.get(builder -> builder.index("user_2025").id(id), T).source();
//
//        log.info("查询信息： {}", JSON.toJSONString(user));
//        return user;
//
//    }

}
//{
//
/// /    @Autowired
/// /    CBEsService cbEsService;
//
//    @Autowired
//    ElasticsearchRestTemplate template;
//
//    /**
//     * 创建索引
//     *
//     * @param
//     * @return
//     * @author
//     * @createAt 2023-07-06 9:03
//     * @updateAt 2023-07-06 9:03
//     */
//    public Boolean initIndex() {
/// /        boolean indexIfNotExist = cbEsService.createIndexIfNotExist(TradeOrderEsIndex.class, true);
//        IndexOperations indexOperations = template.indexOps(User.class);
//        if (!indexOperations.exists()) {
//            boolean res = template.indexOps(User.class).createWithMapping();
//            return res;
//        }
//        log.info("done");
//        return true;
//    }
//
//
/// /    /**
/// /     * 查询数量
/// /     * 建议使用count(tradeOrderSearchFixedDTO, TradeOrderSearchExtDTO)
/// /     *
/// /     * @param
/// /     * @return
/// /     * @author
/// /     * @createAt 2023-07-05 19:26
/// /     * @updateAt 2023-07-05 19:26
/// /     */
/// /    @Deprecated
/// /    public Long count(TradeOrderEsSearchDO tradeOrderSearch) throws IllegalAccessException {
/// /        NativeSearchQueryBuilder query = new NativeSearchQueryBuilder();
/// /        BoolQueryBuilder boolQueryBuilder = buildQuery(tradeOrderSearch);
/// /
/// /        PageRequest pageRequest = PageRequest.of(1, 10, Sort.by(Sort.Direction.DESC, "orderTime"));
/// ///
/// /        query.withQuery(boolQueryBuilder);
/// /        query.withPageable(pageRequest);
/// /        SearchHits<TradeOrderEsIndex> searchHits = template.search(query.build(), TradeOrderEsIndex.class);
/// /
/// ///        SearchHits<TradeOrderEsIndex> searchHits = cbEsService.search(TradeOrderEsIndex.class, query, true);
/// ///        SearchHits<TradeOrderEsIndex> searchHits = cbEsService.search(query.build(), TradeOrderEsIndex.class);
/// /
/// /        return searchHits.getTotalHits();
/// /    }
/// /
/// /    /**
/// /     * 单条更新
/// /     * id存在覆盖， id不存在插入
/// /     *
/// /     * @param tradeOrderEsIndex 单个数据
/// /     * @return
/// /     * @author
/// /     * @createAt 2023-07-10 16:02
/// /     * @updateAt 2023-07-10 16:02
/// /     */
/// /    public boolean saveOrUpdate(TradeOrderEsIndex tradeOrderEsIndex) {
/// /        template.save(tradeOrderEsIndex);
/// ///        cbEsService.saveIndexDoc(tradeOrderEsIndex, null, true);
/// ///        TradeOrderEsIndex save = template.save(tradeOrderEsIndex);
/// /        return true;
/// /    }
/// /
/// /    /**
/// /     * 批量更新
/// /     *
/// /     * @param tradeOrderEsIndices 多个数据
/// /     * @return
/// /     * @author
/// /     * @createAt 2023-07-10 16:01
/// /     * @updateAt 2023-07-10 16:01
/// /     */
/// /    public boolean saveOrUpdate(List<TradeOrderEsIndex> tradeOrderEsIndices) {
/// /        template.save(tradeOrderEsIndices);
/// ///        List<IndexedObjectInformation> res = cbEsService.bulkSaveIndexDoc(TradeOrderEsIndex.class, tradeOrderEsIndices, true);
/// /        return true;
/// /    }
/// /
/// /
/// /    /**
/// /     * 通用查询
/// /     *
/// /     * @author alei
/// /     * @date 2023/8/15 15:54
/// /     */
/// /    public PageInfo<TradeOrderEsIndex> commonSearch(Integer pageNum, Integer pageSize, CommonOrderSearchDO searchDO) {
/// /        try {
/// /            if (null == pageNum) {
/// /                pageNum = 0;
/// /            } else {
/// /                pageNum = pageNum - 1;
/// /            }
/// /            NativeSearchQueryBuilder query = new NativeSearchQueryBuilder();
/// /            BoolQueryBuilder boolQueryBuilder = buildQuery(searchDO);
/// /            PageRequest pageRequest = PageRequest.of(pageNum, pageSize, Sort.by(Sort.Direction.DESC, "orderTime"));
/// ///
/// /            query.withQuery(boolQueryBuilder);
/// /            query.withPageable(pageRequest);
/// /            log.info("es 查询语句：{}", query.build().getQuery().toString());
/// ///            SearchHits<TradeOrderEsIndex> searchHits = cbEsService.search(TradeOrderEsIndex.class, query, true);
/// /            SearchHits<TradeOrderEsIndex> searchHits = template.search(query.build(), TradeOrderEsIndex.class);
/// /
/// /            long total = searchHits.getTotalHits();
/// /
/// /            List<TradeOrderEsIndex> list = new ArrayList<>();
/// /            for (SearchHit<TradeOrderEsIndex> searchHit : searchHits) {
/// /                list.add(searchHit.getContent());
/// /            }
/// /            PageInfo<TradeOrderEsIndex> pageInfo = PageInfo.of(list);
/// /            pageInfo.setTotal(total);
/// /            return pageInfo;
/// /        } catch (Exception e) {
/// /            log.error("搜索订单失败", e);
/// /            throw new RuntimeException(e);
/// /        }
/// /
/// /    }
/// /
/// /    /**
/// /     * 搜索数量
/// /     *
/// /     * @param searchDO
/// /     * @return
/// /     */
/// /    public Long commonSearchCount(CommonOrderSearchDO searchDO) {
/// /        try {
/// /            NativeSearchQueryBuilder query = new NativeSearchQueryBuilder();
/// /            BoolQueryBuilder boolQueryBuilder = buildQuery(searchDO);
/// /            PageRequest pageRequest = PageRequest.of(0, 1);
/// /            query.withQuery(boolQueryBuilder);
/// /            query.withPageable(pageRequest);
/// /            SearchHits<TradeOrderEsIndex> searchHits = template.search(query.build(), TradeOrderEsIndex.class);
/// /
/// ///            SearchHits<TradeOrderEsIndex> searchHits = cbEsService.search(TradeOrderEsIndex.class, query, true);
/// /
/// /            long total = searchHits.getTotalHits();
/// /            return total;
/// /        } catch (Exception e) {
/// /            log.error("搜索订单数量失败", e);
/// /            throw new RuntimeException(e);
/// /        }
/// /
/// /    }
/// /
/// /
/// /    /**
/// /     * 搜索
/// /     *
/// /     * @param pageNum 页码， 从1 开始
/// /     * @return
/// /     * @author
/// /     * @createAt 2023-07-05 19:26
/// /     * @updateAt 2023-07-05 19:26
/// /     */
/// /    @Deprecated
/// /    public PageInfo<TradeOrderEsIndex> search(Integer pageNum, Integer pageSize, TradeOrderEsSearchDO tradeOrderSearch) {
/// /        try {
/// /            if (null == pageNum) {
/// /                pageNum = 0;
/// /            } else {
/// /                pageNum = pageNum - 1;
/// /            }
/// /            NativeSearchQueryBuilder query = new NativeSearchQueryBuilder();
/// /            BoolQueryBuilder boolQueryBuilder = buildQuery(tradeOrderSearch);
/// /            PageRequest pageRequest = PageRequest.of(pageNum, pageSize, Sort.by(Sort.Direction.DESC, "orderTime"));
/// ///
/// /            query.withQuery(boolQueryBuilder);
/// /            query.withPageable(pageRequest);
/// /            SearchHits<TradeOrderEsIndex> searchHits = template.search(query.build(), TradeOrderEsIndex.class);
/// ///            SearchHits<TradeOrderEsIndex> searchHits = cbEsService.search(TradeOrderEsIndex.class, query, true);
/// /
/// /            long total = searchHits.getTotalHits();
/// /
/// /            List<TradeOrderEsIndex> list = new ArrayList<>();
/// /            for (SearchHit<TradeOrderEsIndex> searchHit : searchHits) {
/// /                list.add(searchHit.getContent());
/// /            }
/// /            PageInfo<TradeOrderEsIndex> pageInfo = PageInfo.of(list);
/// /            pageInfo.setTotal(total);
/// /            return pageInfo;
/// /        } catch (Exception e) {
/// /            log.error("搜索订单失败", e);
/// /            throw new RuntimeException(e);
/// /        }
/// /
/// /    }
/// /
/// /    private BoolQueryBuilder buildQuery(TradeOrderEsSearchDO tradeOrderSearch) throws IllegalAccessException {
/// /        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
/// /        Preconditions.checkArgument(null != tradeOrderSearch);
/// /
/// /        TradeOrderEsSearchDO.Term term = tradeOrderSearch.getTerm();
/// /        if (term != null) {
/// /            Field[] termFields = term.getClass().getDeclaredFields();
/// /            for (Field termField : termFields) {
/// /                termField.setAccessible(true);
/// /                Object value = termField.get(term);
/// /                if (null != value) {
/// /                    boolQueryBuilder.must(QueryBuilders.termQuery(termField.getName(), value));
/// /                }
/// /            }
/// /        }
/// /        TradeOrderEsSearchDO.Match match = tradeOrderSearch.getMatch();
/// /        if (null != match) {
/// /            Field[] matchFields = match.getClass().getDeclaredFields();
/// /            boolean hasMatch = false;
/// /            for (Field matchField : matchFields) {
/// /                matchField.setAccessible(true);
/// /                Object value = matchField.get(match);
/// /                if (null != value) {
/// /                    hasMatch = true;
/// /                    boolQueryBuilder.should(QueryBuilders.matchQuery(matchField.getName(), value));
/// /                }
/// /            }
/// /            if (hasMatch) {
/// /                boolQueryBuilder.minimumShouldMatch(1);
/// /            }
/// /        }
/// /
/// /        TradeOrderEsSearchDO.Range range = tradeOrderSearch.getRange();
/// /        if (null != range) {
/// /            Field[] rangeFields = range.getClass().getDeclaredFields();
/// /            for (Field rangeField : rangeFields) {
/// /                rangeField.setAccessible(true);
/// /                Object value = rangeField.get(range);
/// /                if (null != value) {
/// /                    if (value instanceof List == false || ((List) value).size() != 2) {
/// /                        throw new RuntimeException("范围查询请指定范围区间,只接收起止范围两个变量");
/// /                    }
/// /                    List rangeInfo = (List) value;
/// /                    Object from = rangeInfo.get(0);
/// /                    Object to = rangeInfo.get(1);
/// /                    if (from instanceof LocalDateTime) {
/// /                        String fromTmp = ((LocalDateTime) from).format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS"));
/// /                        String toTmp = ((LocalDateTime) to).format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS"));
/// /                        boolQueryBuilder.must(QueryBuilders.rangeQuery(rangeField.getName())
/// /                                .from(fromTmp).to(toTmp).includeLower(true).includeUpper(false));
/// /                    } else {
/// /                        boolQueryBuilder.must(QueryBuilders.rangeQuery(rangeField.getName())
/// /                                .from(rangeInfo.get(0)).to(rangeInfo.get(1)).includeLower(true).includeUpper(false));
/// /                    }
/// /
/// /                }
/// /            }
/// /        }
/// /        TradeOrderEsSearchDO.Terms terms = tradeOrderSearch.getTerms();
/// /        if (null != terms) {
/// /            Field[] termsFields = terms.getClass().getDeclaredFields();
/// /            for (Field termsField : termsFields) {
/// /                termsField.setAccessible(true);
/// /                Object value = termsField.get(terms);
/// /                if (null != value && value instanceof List) {
/// /                    List termsInfo = (List) value;
/// /                    if (termsInfo.size() == 0) {
/// /                        break;
/// /                    }
/// /                    String[] termsArr = new String[termsInfo.size()];
/// /                    for (int i = 0; i < termsInfo.size(); i++) {
/// /                        termsArr[i] = termsInfo.get(i) + "";
/// /                    }
/// /                    boolQueryBuilder.must(QueryBuilders.termsQuery(termsField.getName(), termsArr));
/// /                }
/// /            }
/// /        }
/// /        return boolQueryBuilder;
/// /    }
/// /
/// /
/// /    private BoolQueryBuilder buildQuery(CommonOrderSearchDO searchDO) throws IllegalAccessException {
/// ///    转换日期格式
/// /        transferDateToString(searchDO);
/// /
/// /        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
/// /        Preconditions.checkArgument(null != searchDO);
/// /        Map<String, Object> term = searchDO.getTerm();
/// /        if (term != null) {
/// /            term.keySet().stream().forEach(key -> {
/// /                Object val = term.get(key);
/// /                if (null != val) {
/// /                    if (val instanceof List) {
/// /                        List list = (List) val;
/// /                        list.forEach(item -> {
/// /                            boolQueryBuilder.must(QueryBuilders.termQuery(key, item));
/// /                        });
/// /                    } else {
/// /                        boolQueryBuilder.must(QueryBuilders.termQuery(key, val));
/// /                    }
/// /                }
/// /            });
/// /        }
/// /        Map<String, Object> match = searchDO.getMatch();
/// /        if (null != match) {
/// /            AtomicInteger matchSegCount = new AtomicInteger();
/// /            match.keySet().stream().forEach(key -> {
/// /                if (null != match.get(key)) {
/// /                    matchSegCount.getAndIncrement();
/// /                    boolQueryBuilder.should(QueryBuilders.matchQuery(key, match.get(key)));
/// /                }
/// /            });
/// /            if (matchSegCount.get() > 0) {
/// /                boolQueryBuilder.minimumShouldMatch(matchSegCount.get());
/// /            }
/// /        }
/// /
/// /        Map<String, List> range = searchDO.getRange();
/// /        if (null != range) {
/// /            range.keySet().stream().forEach(key -> {
/// /                List<Object> rangeValue = range.get(key);
/// /                if (CollectionUtils.isEmpty(rangeValue) || rangeValue.size() != 2) {
/// /                    throw new CustomException("范围查询请指定范围区间，只接受list，且要求元素数量为2");
/// /                }
/// /                boolQueryBuilder.must(QueryBuilders.rangeQuery(key)
/// /                        .from(rangeValue.get(0)).to(rangeValue.get(1)).includeLower(true).includeUpper(false));
/// /            });
/// /        }
/// /        Map<String, List> terms = searchDO.getTerms();
/// /        if (null != terms) {
/// /            terms.keySet().stream().forEach(key -> {
/// /                List<Object> termsValue = terms.get(key);
/// /                if (CollectionUtils.isNotEmpty(termsValue)) {
/// /                    boolQueryBuilder.must(QueryBuilders.termsQuery(key, termsValue));
/// /                }
/// /
/// /            });
/// /        }
/// /        return boolQueryBuilder;
/// /    }
/// /
/// /    /**
/// /     * 转换通用查询参数，
/// /     * date 到 string
/// /     * localdatetime 到string
/// /     */
/// /    private void transferDateToString(CommonOrderSearchDO searchDO) {
/// /        if (null == searchDO) {
/// /            return;
/// /        }
/// /        Map<String, Object> term = searchDO.getTerm();
/// /        Map<String, List> terms = searchDO.getTerms();
/// /        Map<String, Object> match = searchDO.getMatch();
/// /        Map<String, List> range = searchDO.getRange();
/// /        rewriteMapVal(term);
/// /        rewriteMapVal(terms);
/// /        rewriteMapVal(match);
/// /        rewriteMapVal(range);
/// /    }
/// /
/// /    /**
/// /     * 重写map中的val值， 针对date，localDatetime类型
/// /     */
/// /    private void rewriteMapVal(Map map) {
/// /        map.keySet().forEach(key -> {
/// /            Object val = map.get(key);
/// /            if (null != val) {
/// /                if (val instanceof LocalDateTime) {
/// /                    String format = ((LocalDateTime) val).format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS"));
/// /                    map.put(key, format);
/// /                } else if (val instanceof List) {
/// /                    List list = (List) val;
/// /                    if (CollectionUtils.isNotEmpty(list) && list.get(0) instanceof LocalDateTime) {
/// /                        List<String> res = new ArrayList<>();
/// /                        for (Object item : list) {
/// /                            String itemVal = ((LocalDateTime) item).format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS"));
/// /                            res.add(itemVal);
/// /                        }
/// /                        map.put(key, res);
/// /                    } else if (CollectionUtils.isNotEmpty(list) && list.get(0) instanceof Date) {
/// /                        List<String> res = new ArrayList<>();
/// /                        for (Object item : list) {
/// /                            String itemVal = DateFormatUtils.format((Date) item, "yyyy-MM-dd'T'HH:mm:ss.SSS");
/// /                            res.add(itemVal);
/// /                        }
/// /                        map.put(key, res);
/// /                    }
/// /                } else if (val instanceof Date) {
/// /                    String format = DateFormatUtils.format((Date) val, "yyyy-MM-dd'T'HH:mm:ss.SSS");
/// /                    map.put(key, format);
/// /                }
/// /            }
/// /        });
/// /
/// /
/// /    }
//
//
//}